﻿using NewLife.Log;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Diagnostics.Contracts;
using System.IO;
using System.Text.RegularExpressions;

namespace PtlSave.Util
{
    public class CommonUtil
    {
        //字符串编码
        public static string encode = "GB2312";

        /*
         * 读取json
         * example string id = (int)jsonObject["id"]; string ip = jsonObject["ip"].ToString();
         */
        public static JObject GetJson(string jsonPath)
        {
            try
            {
                StreamReader file = File.OpenText(jsonPath);
                JsonTextReader reader = new JsonTextReader(file);
                JObject jsonObject = (JObject)JToken.ReadFrom(reader);
                file.Close();
                return jsonObject;
            }
            catch (Exception e)
            {
                XTrace.WriteLine(jsonPath + "读取异常，" + e.Message);
                return null;
            }
        }

        /*
         * 写json
         * 多层key，间隔“.”
         */
        public static void SetJson(string jsonPath, string key, string value)
        {
            try
            {
                string json = File.ReadAllText(jsonPath);
                dynamic jsonObj = JsonConvert.DeserializeObject(json);
                if (!"".Equals(key))
                {
                    string[] keyArr = key.Split('.');
                    switch (keyArr.Length)
                    {
                        case 1:
                            jsonObj[keyArr[0]] = value;
                            break;
                        case 2:
                            jsonObj[keyArr[0]][keyArr[1]] = value;
                            break;
                        case 3:
                            jsonObj[keyArr[0]][keyArr[1]][keyArr[2]] = value;
                            break;
                        case 4:
                            jsonObj[keyArr[0]][keyArr[1]][keyArr[2]][keyArr[3]] = value;
                            break;
                        case 5:
                            jsonObj[keyArr[0]][keyArr[1]][keyArr[2]][keyArr[3]][keyArr[4]] = value;
                            break;
                        case 6:
                            jsonObj[keyArr[0]][keyArr[1]][keyArr[2]][keyArr[3]][keyArr[4]][keyArr[5]] = value;
                            break;
                        default:
                            jsonObj["key"] = value;
                            break;
                    }
                }
                string output = JsonConvert.SerializeObject(jsonObj, Formatting.Indented);
                File.WriteAllText(jsonPath, output);
            }
            catch (Exception e)
            {
                XTrace.WriteLine("写" + jsonPath + " " + key + " " + value + "异常，" + e.Message);
            }
        }

        public static bool IsInt(string value)
        {
            return Regex.IsMatch(value, @"^[+-]?\d*$");
        }

        /*
         * 获取格式化后的当前时间
         */
        public static string GetFormatDatetime(String format = "")
        {
            if ("".Equals(format) || format == null)
            {
                format = "yyyy-MM-dd HH:mm:ss.fff";
            }
            return string.Format("{0:" + format + "}", DateTime.Now);
        }

        /*
         * 获取时间戳
         */
        public static string GetTimeStamp()
        {
            TimeSpan ts = DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            //return Convert.ToInt64(ts.Ticks).ToString();
            return Convert.ToInt64(ts.TotalMilliseconds).ToString();
        }

        /**
         * 将byte数组转为16进制
         * bytes
         */
        public static string byteToHex(byte[] bytes)
        {
            string returnStr = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                returnStr += bytes[i].ToString("X2");
            }
            //return BitConverter.ToString(bytes);
            return returnStr;
        }

        /*
         * byte数组转IP格式，针对特定byte数组的处理
         */
        public static string BytesToFormatIp(byte[] bytes)
        {
            string result = "";
            foreach (byte b in bytes)
            {
                result += "." + b.ToString();
            }
            result = result.Substring(1);
            return result;
        }

        /*
         * 标准格式IP地址转byte数组 
         */
        public static byte[] FormatIpToBytes(string ipAddr)
        {
            byte[] btIp = new byte[4];
            string[] ipAddrArr = ipAddr.Split('.');
            for (int i = 0; i < (ipAddrArr.Length > 4 ? 4 : ipAddrArr.Length); i++)
            {
                if (IsInt(ipAddrArr[i]))
                {
                    byte[] bti = IntToByteArray(int.Parse(ipAddrArr[i]), true, false);
                    if (bti.Length > 0)
                    {
                        btIp[i] = bti[0];
                    }
                }
            }
            return btIp;
        }

        /**
         * int到byte[]，转换与ByteArrayToInt配合使用
         * asc为true，则为由高位到低位，否则反之
         * isZero为true，则保留空位，否则反之
         * @param i
         * @param asc
         * @param isZero
         * @return
         */
        public static byte[] IntToByteArray(int i, Boolean asc, Boolean isZero)
        {
            byte[] tmpBtArr = new byte[4];
            int l = 0;
            for (int n = 0; n < 4; n++)
            {
                tmpBtArr[n] = asc ? (byte)((i >> (3 - n) * 8) & 0xFF) : (byte)((i >> n * 8) & 0xFF);
                l += isZero ? 1 : (tmpBtArr[n] == 0 ? 0 : 1);
            }
            byte[] result = new byte[l];
            if (!isZero)
            {
                if (asc)
                {
                    Buffer.BlockCopy(tmpBtArr, 4 - l, result, 0, l);
                }
                else
                {
                    Buffer.BlockCopy(tmpBtArr, 0, result, 0, l);
                }
            }
            else
            {
                result = tmpBtArr;
            }
            return result;
        }

        /**
         * byte[]转int，转换与IntToByteArray配合使用
         * isZero为true，则保留空位，否则反之
         * isInv为true，则为由高位到低位，否则反之
         * bytes
         */
        public static int ByteArrayToInt(byte[] bytes, Boolean isInv, Boolean isZero)
        {
            int value = 0;
            for (int i = 0; i < bytes.Length; i++)
            {
                int shift = (isInv ? (3 - i - (isZero ? 0 : (4 - bytes.Length))) : i) * 8;
                value += (bytes[i] & 0xFF) << shift;
            }
            return value;
        }

        /*
         * long转byte[]
         */
        public static byte[] LongToBytes(long s, bool asc)
        {
            byte[] buf = new byte[8];
            if (asc)
                for (int i = buf.Length - 1; i >= 0; i--)
                {
                    buf[i] = (byte)(s & 0x00000000000000ff);
                    s >>= 8;
                }
            else
                for (int i = 0; i < buf.Length; i++)
                {
                    buf[i] = (byte)(s & 0x00000000000000ff);
                    s >>= 8;
                }
            return buf;
        }
    }
}
